#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

char* SERVERIP = "127.0.0.1";
const int N = 2048;
#define ERR_EXIT(m)     \
  do {                  \
    perror(m);          \
    exit(EXIT_FAILURE); \
  } while (0)

class UdpClient {
 public:
  UdpClient(int cli_port) : cli_port_(cli_port) {
    if ((cli_fd_ = socket(PF_INET, SOCK_DGRAM, 0)) < 0) ERR_EXIT("socket");
  }
  ~UdpClient() { close(cli_fd_); }
  void Loop() {
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(10005);
    servaddr.sin_addr.s_addr = inet_addr(SERVERIP);

    int ret;
    while (fgets(buf_send_, sizeof(buf_send_), stdin) != NULL) {
      printf("向服务器发送：%s\n", buf_send_);
      sendto(cli_fd_, buf_send_, strlen(buf_send_), 0,
             (struct sockaddr*)&servaddr, sizeof(servaddr));

      ret = recvfrom(cli_fd_, buf_recv_, sizeof(buf_recv_), 0, NULL, NULL);
      if (ret == -1) {
        if (errno == EINTR) continue;
        ERR_EXIT("recvfrom");
      }
      printf("从服务器接收：%s\n", buf_recv_);

      memset(buf_send_, 0, sizeof(buf_send_));
      memset(buf_recv_, 0, sizeof(buf_recv_));
    }
  }

 private:
 private:
  int cli_fd_;
  int cli_port_;
  char buf_recv_[N];
  char buf_send_[N];
};
int main(void) {
  UdpClient udp_client(10004);
  udp_client.Loop();
  return 0;
}
// g++ -o udp_cli udp_cli.cc -std=c++11